package com.hushao.aimi.service.impl;

import com.hushao.aimi.DateUtil;
import com.hushao.aimi.common.PageVo;
import com.hushao.aimi.common.ServerResponse;
import com.hushao.aimi.entity.AimiCategory;
import com.hushao.aimi.vo.CategoryVo;
import com.hushao.aimi.repository.CategoryRepository;
import com.hushao.aimi.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;


/**
 * @description: 分类服务类
 * @author: 胡少
 * @create: 2018-06-06 11:41
 **/
@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryRepository categoryRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse addCategory(CategoryVo categoryVo) throws Exception{
        if(categoryVo.getParentId() == null ||categoryVo.getName() == null || "".equals(categoryVo.getName())){
            log.error("添加分类参数错误");
            return ServerResponse.Error("添加分类参数错误");
        }
        AimiCategory category=new AimiCategory(categoryVo.getParentId(),categoryVo.getName(),categoryVo.getSortOrder());
        categoryRepository.save(category);
        log.info("添加品类成功！");
        return ServerResponse.Success("添加品类成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse updateCategory(CategoryVo vo) throws Exception{
        if(!vo.getStatus() && vo.getParentId() == 0){
            log.error("修改失败，其父类下有子类，不得禁用");
            return ServerResponse.Error("修改失败，其父类下有子类，不得禁用");
        }
        if(vo.getParentId()!=0){
            List<AimiCategory> c=categoryRepository.findByParentId(vo.getId());
            if(c.size()>0){
                log.error("更新分类失败：其有子分类：｛｝",vo.getId());
                return ServerResponse.Error("更新分类失败：其有子分类｝");
            }
        }
        if(vo.getParentId() == null ||vo.getName() == null || "".equals(vo.getName())){
            log.error("更新分类参数错误");
            return ServerResponse.Error("更新分类参数错误");
        }
        Optional<AimiCategory> optional=categoryRepository.findById(vo.getId());
        AimiCategory category=optional.map(o->{
            o.setParentId(vo.getParentId());
            o.setName(vo.getName());
            o.setSortOrder(vo.getSortOrder());
            o.setStatus(vo.getStatus());
            return o;
        }).orElseThrow(()->new RuntimeException("错误！"));
        //更新与数据库同步
        categoryRepository.flush();
        log.info("更新品类成功！{}",category);
        return ServerResponse.Success("更新品类成功！");
    }

    @Override
    public ServerResponse getChildrenParallelCategory(Integer categoryId) throws Exception {
        List<CategoryVo> categories=categoryRepository.findByParentId(categoryId)
                .stream()
                .map(c->new CategoryVo(c.getId(),c.getName())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(categories)){
            log.info("未找到当前分类");
        }
        return ServerResponse.Success(categories);
    }

    @Override
    public ServerResponse getCategoryAndChildrenById(Integer categoryId) {
        Set<AimiCategory> categorySet= new HashSet<>();
        findChildCategoiry(categorySet,categoryId);
        List<Integer> categoryIds=new ArrayList<>();
        if(categoryId!=null){
            for(AimiCategory c:categorySet){
                categoryIds.add(c.getId());
            }
        }
        return ServerResponse.Success(categoryIds);
    }


    private Set<AimiCategory> findChildCategoiry(Set<AimiCategory> categorySet,Integer categoryId){
        Optional<AimiCategory> category=categoryRepository.findById(categoryId);
        category.ifPresent(categorySet::add);
        //查询子节点分类
        List<AimiCategory> categories=  categoryRepository.findByParentId(categoryId);

        for (AimiCategory c:categories){
            findChildCategoiry(categorySet,c.getId());
        }
        return categorySet;
    }


    @Override
    public ServerResponse getCategoryByNameLike(String name, Pageable pageable) {
        name="%"+name+"%";
        Page<AimiCategory> page=categoryRepository.findByNameLike(name,pageable);
            List<CategoryVo> categoryVos=page.getContent().stream().map(c->{
                String parentName=null;
                //是否是子类
                if(c.getParentId()!=0){
                  Optional<AimiCategory> ac= categoryRepository.findById(c.getParentId());
                  parentName=ac.get().getName();
                }
                return  new CategoryVo(c.getId(),
                        c.getParentId(), parentName,
                        c.getName(),c.getStatus(),
                        c.getSortOrder(),DateUtil.getDateTimeOfTimestamp(c.getCreateTime()),
                        DateUtil.getDateTimeOfTimestamp(c.getUpdateTime()),c.getComment());

            }).collect(Collectors.toList());
        PageVo pageVo=new PageVo(page);
        Map<String,Object> map=new HashMap<>(2);

        map.put("page",pageVo);
        map.put("products",categoryVos);
        return ServerResponse.Success(map);
    }

    @Override
    public ServerResponse listCategory() {
        //子分类
        List<AimiCategory> categorieChilds=categoryRepository.findByParentIdNot(0);

        //父分类
        List<CategoryVo> aimiCategories=categoryRepository.findByParentId(0).stream()
                .map(c-> new CategoryVo(c.getId(),c.getName())).collect(Collectors.toList());

        for(CategoryVo c:aimiCategories){
            List<CategoryVo> categories=categorieChilds.stream()
                    .filter(c1->c1.getParentId().equals(c.getId()))
                    .map(c2-> new CategoryVo(c2.getId(),c2.getName()))
                    .collect(Collectors.toList());
            c.setChildCategroys(categories);

        }

        return ServerResponse.Success(aimiCategories);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServerResponse delCategory(Integer categoryId) {
        List<AimiCategory> c=categoryRepository.findByParentId(categoryId);
        if(c.size()>0){
            log.error("删除品类失败:,{categoryId}",categoryId);
            return ServerResponse.Error("删除品类失败，因为有子品类");
        }
        categoryRepository.deleteById(categoryId);
        log.info("删除品类成功！");
        return ServerResponse.Success("删除品类成功！");
    }

}
